#ifndef _C_S_R_
#define _C_S_R_

#include <iostream>
#include <stdlib.h>
#include <string>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
class SMatrix {
  // protected:
public:
  int row_num; //矩阵的行数mu
  int col_num; //矩阵的列数nu
  int tot_num; //矩阵中非零数据元素的个数tu
  vector<int> row_offsets;
  vector<int> col_indices;
  vector<double> vec_D;
  vector<int> vec_I;
  int flag_int_double; // 0: Int 1: double
  // public:
  SMatrix();
  void build(vector<vector<double>> mat);
  void build(vector<vector<int>> mat);
  int build(vector<vector<double>> mat, vector<int> &row_off,
            vector<int> &col_ind, vector<double> &vec_val);
  int build(vector<vector<int>> mat, vector<int> &row_off, vector<int> &col_ind,
            vector<int> &vec_val);
  double Access(int row, int col);
  // double Access(int row_size, int col_size, vector<int> &row_off,
  //               vector<int> &col_ind, vector<double> &vec, int row, int col);
  void MDisplay(); //遍历矩阵，并输出非零数据元素的值
  void Rebuild(vector<vector<double>> &mat_R); // 重建矩阵
  void Rebuild(vector<vector<int>> &mat_R);    // 重建矩阵

  void check_Two_mat(vector<vector<double>> mat, vector<vector<double>> mat_R);
  void clear();
  // void test();
};

class SMatrix_Ch : public SMatrix {
  // add a channel dimension
public:
  int size_ch;
  vector<int> row_num_ch;
  vector<int> col_num_ch;
  vector<int> tot_num_ch;
  vector<vector<int>> row_off_ch;
  vector<vector<int>> col_ind_ch;
  vector<vector<double>> vec_D_ch;
  vector<vector<int>> vec_I_ch;
  vector<int> row_off_cal, col_ind_cal, vec_I_cal;
  vector<double> vec_D_cal;
  int tot_num_cal;
  int row_size_cal, col_size_cal;
  int flag_int_double_ch; // 0: Int 1: double
  int EPS = 0.00000000000000000001;

  SMatrix_Ch();
  //  ---- build sep ----
  void init_ch(int size_ch, int type);
  int Flag_init_ch = -1;
  void build_ch(vector<vector<double>> &mat_ch_sep, int ch);
  void build_ch(vector<vector<int>> &mat_ch_sep, int ch);
  //  ---- build together ---
  void build_ch(vector<vector<vector<double>>> &mat_ch);
  void build_ch(vector<vector<vector<int>>> &mat_ch);
  //
  double val(int &ch, int &row, int &col);

  void Rebuild(vector<vector<vector<double>>> &mat_R);
  void Rebuild(vector<vector<vector<int>>> &mat_R);
  void check_Two_mat(vector<vector<vector<double>>> &mat,
                     vector<vector<vector<double>>> &mat_R);

  // build out side
  void cal_init(int ch_size, int type); // int : type = 0  double : 1
  void cal_beg(int row_size, int col_size);
  void cal_row_off(int ch, int i);
  int cal_col_ind(int ch, int i, int j, double val);
  int cal_col_ind(int ch, int i, int j, int val);
  void cal_end(int ch);
  //
  void clear();
};

#endif
